from rest_framework.decorators import action
from datetime import datetime
from django.utils import timezone

from dvadmin.system.models import ActivityParameter, Goods
from dvadmin.utils.json_response import DetailResponse, ErrorResponse, SuccessResponse
from dvadmin.utils.serializers import CustomModelSerializer
from dvadmin.utils.viewset import CustomModelViewSet


class ActivityParameterSerializer(CustomModelSerializer):
    """
    Activity management interface - serializer
    """

    class Meta:
        model = ActivityParameter
        fields = "__all__"
        read_only_fields = ["id"]


class ActivityParameterCreateUpdateSerializer(CustomModelSerializer):
    """
    Activity management interface - serializer for creating/updating
    """

    def validate(self, attrs: dict):
        return super().validate(attrs)

    class Meta:
        model = ActivityParameter
        fields = '__all__'


class ActivityParameterViewSet(CustomModelViewSet):
    """
    Activity parameter management interface
    """
    queryset = ActivityParameter.objects.all()
    serializer_class = ActivityParameterSerializer

    @action(methods=['GET'], detail=False)
    def get_settings(self, request):
        """Get activity parameter settings"""
        try:
            # Get prize type enums
            prize_types = [
                {'value': choice[0], 'label': choice[1]} 
                for choice in ActivityParameter.PRIZE_TYPE_CHOICES
            ]
            
            # Get activity status enums
            activity_statuses = [
                {'value': choice[0], 'label': choice[1]} 
                for choice in ActivityParameter.ACTIVITY_STATUS_CHOICES
            ]
            
            # Get available goods for prize type 4 (商品)
            goods_list = []
            if Goods.objects.exists():
                goods_list = Goods.objects.values('id', 'goods_name', 'goods_price', 'goods_image')
                goods_list = [
                    {
                        'value': item['id'],
                        'label': item['goods_name'],
                        'price': item['goods_price'],
                        'image': item['goods_image']
                    } 
                    for item in goods_list
                ]

            data = {
                'prize_types': prize_types,
                'activity_statuses': activity_statuses,
                'goods_list': goods_list
            }
            
            return DetailResponse(data=data, msg="Successfully retrieved settings")
            
        except Exception as e:
            return ErrorResponse(msg=f"Failed to get settings: {str(e)}")

    def create(self, request, *args, **kwargs):
        """Create activity parameter"""
        try:
            data = request.data
            prize_type = data.get('activity_type')
            
            # 验证奖品类型相关的数据
            if prize_type == 1:  # 订单打折券
                if 'discount_value' not in data:
                    return ErrorResponse(msg="Discount value is required for order discount coupon")
                if float(data['discount_value']) <= 0 or float(data['discount_value']) >= 1:
                    return ErrorResponse(msg="Discount value must be between 0 and 1")
                data['activity_awards'] = f"订单{float(data['discount_value'])*10}折券"
                
            elif prize_type == 2:  # 商品券
                if not data.get('goods_id'):
                    return ErrorResponse(msg="Goods ID is required for goods coupon")
                goods = Goods.objects.filter(id=data['goods_id']).first()
                if not goods:
                    return ErrorResponse(msg="Goods not found")
                # 使用商品信息
                data['activity_awards'] = f"{goods.goods_name}商品券"
                
            elif prize_type == 3:  # 商品打折券
                if not data.get('goods_id'):
                    return ErrorResponse(msg="Goods ID is required for goods discount coupon")
                if 'discount_value' not in data:
                    return ErrorResponse(msg="Discount value is required for goods discount coupon")
                if float(data['discount_value']) <= 0 or float(data['discount_value']) >= 1:
                    return ErrorResponse(msg="Discount value must be between 0 and 1")
                goods = Goods.objects.filter(id=data['goods_id']).first()
                if not goods:
                    return ErrorResponse(msg="Goods not found")
                # 使用商品信息
                data['activity_awards'] = f"{goods.goods_name}{float(data['discount_value'])*10}折券"
                
            elif prize_type == 4:  # 实物奖励
                if not data.get('activity_awards'):
                    return ErrorResponse(msg="Prize name is required for physical prize")
                if not data.get('activity_img'):
                    return ErrorResponse(msg="Prize image is required for physical prize")
                    
            return super().create(request, *args, **kwargs)
            
        except Exception as e:
            return ErrorResponse(msg=f"Failed to create activity parameter: {str(e)}")

    @action(methods=['GET'], detail=True)
    def role_get_menu(self, request):
        app_user_queryset = ActivityParameter.objects.filter(users__id=request.user.id).values_list('data_range', flat=True)
        return DetailResponse(data=app_user_queryset)

    @action(detail=True, methods=['get'])
    def statistics(self, request, pk=None):
        """Get activity statistics data"""
        try:
            activity = self.get_object()
            data = {
                'participant_count': activity.participant_count,
                'conversion_rate': self.calculate_conversion_rate(activity),
                'reward_distributed': self.get_reward_statistics(activity)
            }
            return SuccessResponse(data=data, msg="Successfully retrieved statistics")
        except Exception as e:
            return ErrorResponse(msg=f"Failed to get statistics: {str(e)}")
    
    @action(detail=False, methods=['post'])
    def update_status(self, request):
        """Update activity status"""
        try:
            current_time = timezone.now()
            # Update ended activities
            self.get_queryset().filter(
                end_time__lt=current_time,
                activity_status=1
            ).update(activity_status=2)
            # Update started activities
            self.get_queryset().filter(
                start_time__lte=current_time,
                end_time__gt=current_time,
                activity_status=0
            ).update(activity_status=1)
            return SuccessResponse(msg="Activity status updated successfully")
        except Exception as e:
            return ErrorResponse(msg=f"Failed to update activity status: {str(e)}")
